package com.fuang.extendsandsuper;

import java.util.*;

/**
 * Created by Fuang on 2017-6-27.
 * ? extends 通配符的作用：
 * 1，方法参数类型为T时，则可以传T的子类对象进去，就像子类赋值给父类
 * 2，扩展方法参数的通用性：Collection<T>,参数是泛型时，无法传Collection<T的子类>，所以需要将Collection<T>改成Collection<? extends T>,则可以传Collection<T的子类>：
 *    像List的addAll方法，支持List<T的子类>，而且get出来都是可以复制给T类型的对象。一般jdk中在 addAll、putAll、pushAll这类的接口的参数中使用。
 * ? extends 通配符的特性：
 * 1，无法给? extends的泛型类型的实例对象add任何对象进去
 * ? super 通配符的作用：
 * 1，
 *
 * effective java:
 * PECS
 */
public class Demo {

    /**
     * ? extends 的demo
     */
    public void extendsDemo() {
        // 1，方法参数类型为T时，则可以传T的子类对象进去，就像子类赋值给父类
        List<Fruit> fruitList = new ArrayList<>();
        fruitList.add(new Apple());
        fruitList.add(new Strawberry());

        // 2，Collection<T>,参数是泛型时，无法传Collection<T的子类>，所以需要将Collection<T>改成Collection<? extends T>,则可以传Collection<T的子类>，扩展发放的通用性
        TestList<Fruit> testList = new TestList<>();
        TestList<Apple> appleTestList = new TestList<>();
        // testList.addAllNo(appleTestList); // addAllNo方法的参数是Collection<E> c， 使用子类的泛型会报错
        testList.addAll(appleTestList); // 采用 Collection<? extends T>,则可以传Collection<T的子类>

        // 特性1，无法给? extends的泛型类型的实例对象add任何对象进去
        List<Apple> apples = new ArrayList<>();
        List<? extends Fruit> fruits = apples; // fruits是不能再add任何对象进去了。即使是fruits.add(new Fruits())都会报错。
        // fruits.addAll(apples); // 会报错
        // fruits.add(new Fruits()); // 会报错
    }

    public void supderDemo() {
        Object[] objects = new Long[1];

    }

}
